<?php

namespace app\common\utils;

class Tree
{

    /**
     * @param int $id
     * @param array $data [['id' => '', 'pid' => ''], ['id' => '', 'pid' => ''] ...]
     * @param bool $oneself
     * @return array
     */
    public static function childrenIds(int $id, array $data, bool $oneself = false): array
    {
        $childrenIds = [];
        if ($oneself) {
            $childrenIds[] = $id;
        }

        foreach ($data as $key => $item) {
            if (!isset($item['id']) || !isset($item['pid'])) {
                unset($data[$key]);
                continue;
            }
            if ($item['pid'] === $id) {
                $childrenIds[] = $item['id'];
                unset($data[$key]);
                $childrenIds = array_merge($childrenIds, self::childrenIds($item['id'], $data));
            }
        }

        return $childrenIds;
    }

    /**
     * @param int $id
     * @param array $data [['id' => '', 'pid' => ''], ['id' => '', 'pid' => ''] ...]
     * @param bool $oneself
     * @return array
     */
    public static function childrenData(int $id, array $data, bool $oneself = false): array
    {
        $childrenData = [];

        foreach ($data as $key => $item) {
            if (!isset($item['id']) || !isset($item['pid'])) {
                unset($data[$key]);
                continue;
            }
            if ($oneself && $item['id'] === $id) {
                $childrenData[] = $item;
            }
            if ($item['pid'] === $id) {
                $childrenData[] = $item;
                unset($data[$key]);
                $childrenData = array_merge($childrenData, self::childrenData($item['id'], $data));
            }
        }

        return $childrenData;
    }

    /**
     * @param array $data [['id' => '', 'pid' => ''], ['id' => '', 'pid' => ''] ...]
     * @param int $pid
     * @return array
     */
    public static function childrenDataByTree(array $data, int $pid = 0): array
    {
        $childrenData = [];

        foreach ($data as $key => $item) {
            if (!isset($item['id']) || !isset($item['pid'])) {
                unset($data[$key]);
                continue;
            }

            if ($item['pid'] === $pid) {
                unset($data[$key]);
                $item['children'] = self::childrenDataByTree($data, $item['id']);
                $childrenData[] = $item;
            }
        }

        return $childrenData;
    }

    /**
     * @param int $id
     * @param array $data [['id' => '', 'pid' => ''], ['id' => '', 'pid' => ''] ...]
     * @param bool $oneself
     * @return array
     */
    public static function parentIds(int $id, array $data, bool $oneself = false): array
    {
        $parentIds = [];
        if ($oneself) {
            $parentIds[] = $id;
        }

        foreach ($data as $key => $item) {
            if (!isset($item['id']) || !isset($item['pid'])) {
                unset($data[$key]);
                continue;
            }
            if ($item['id'] === $id) {
                if (empty($item['pid'])) {
                    break;
                }
                $parentIds[] = $item['pid'];
                unset($data[$key]);
                $parentIds = array_merge($parentIds, self::parentIds($item['pid'], $data));
            }
        }

        return $parentIds;
    }

    /**
     * @param int $id
     * @param array $data [['id' => '', 'pid' => ''], ['id' => '', 'pid' => ''] ...]
     * @param bool $oneself
     * @return array
     */
    public static function parentData(int $id, array $data, bool $oneself = false): array
    {
        $parentData = [];

        foreach ($data as $key => $item) {
            if (!isset($item['id']) || !isset($item['pid'])) {
                unset($data[$key]);
                continue;
            }
            if ($item['id'] === $id) {
                if ($oneself) {
                    $parentData[] = $item;
                }
                if (empty($item['pid'])) {
                    break;
                }
                unset($data[$key]);
                $parentData = array_merge($parentData, self::parentData($item['pid'], $data, true));
            }
        }

        return $parentData;
    }

    /**
     * @param int $id
     * @param array $data [['id' => '', 'pid' => ''], ['id' => '', 'pid' => ''] ...]
     * @return array
     */
    public static function parentDataByTree(int $id, array $data): array
    {
        return self::childrenDataByTree(self::parentData($id, $data, true));
    }
}